package com.andova.camera.glsurface

import android.content.Context
import android.graphics.Bitmap
import android.opengl.GLES11Ext
import android.opengl.GLES30
import com.andova.ext.i
import com.andova.ext.printDelay
import com.andova.face.detector.IPreview
import com.andova.glcamera.glsurface.CameraGLSurfaceView
import java.io.InputStream
import java.nio.ByteBuffer
import java.nio.ByteOrder


class ASampleProvider(private val previewer: IPreview) : CameraGLSurfaceView.Provider {
    private var matLoc = -1
    private var samLoc = -1
    private var width = -1
    private var height = -1
    private fun getInstr(instr: InputStream): String = String(instr.readBytes())
    override fun vertexGLSL(context: Context): String = getInstr(context.assets.open("v_texture_oes.glsl"))
    override fun fragmentGLSL(context: Context): String = getInstr(context.assets.open("f_texture_oes.glsl"))
    override fun onSurfaceCreated(program: Int) {
        GLES30.glUseProgram(program)
        previewer.openCamera()
        matLoc = GLES30.glGetUniformLocation(program, "uTexMat")
        samLoc = GLES30.glGetUniformLocation(program, "yuvTexSampler")
    }

    override fun onSurfaceChanged(width: Int, height: Int) {
        this.width = width
        this.height = height
        i(GLES30.glGetString(GLES30.GL_EXTENSIONS))
        GLES30.glViewport(0, 0, width, height)
    }

    override fun onDrawFrame(textureId: Int, transformMatrix: FloatArray) {
//        printCounter("onDrawFrame")
        //激活纹理单元0
        GLES30.glActiveTexture(GLES30.GL_TEXTURE0)
        //绑定外部纹理到纹理单元0
        GLES30.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureId)
        //将此纹理单元创为片段着色器的uTextureSampler外部纹理采样器
        GLES30.glUniform1i(samLoc, 0)

        val vertexData = floatArrayOf(
                0f, 0f, 0f,     //顶点坐标V0
                1f, 1f, 0f,     //顶点坐标V1
                -1f, 1f, 0f,    //顶点坐标V2
                -1f, -1f, 0f,   //顶点坐标V3
                1f, -1f, 0f     //顶点坐标V4
        )
        val vertexBuffer = ByteBuffer.allocateDirect(vertexData.size * 4).order(ByteOrder.nativeOrder()).asFloatBuffer().put(vertexData).position(0)

        val texPosData = floatArrayOf(
                0.5f, 0.5f,     //纹理坐标V0
                1f, 1f,         //纹理坐标V1
                0f, 1f,         //纹理坐标V2
                0f, 0.0f,       //纹理坐标V3
                1f, 0.0f        //纹理坐标V4
        )
        val texPosBuffer = ByteBuffer.allocateDirect(texPosData.size * 4).order(ByteOrder.nativeOrder()).asFloatBuffer().put(texPosData).position(0)

        val indexData = shortArrayOf(
                0, 1, 2,        //V0,V1,V2 三个顶点组成一个三角形
                0, 2, 3,        //V0,V2,V3 三个顶点组成一个三角形
                0, 3, 4,        //V0,V3,V4 三个顶点组成一个三角形
                0, 4, 1         //V0,V4,V1 三个顶点组成一个三角形
        )
        val vertexIndexBuffer = ByteBuffer.allocateDirect(indexData.size * 2).order(ByteOrder.nativeOrder()).asShortBuffer().put(indexData).position(0)

        //将纹理矩阵传给片段着色器
        GLES30.glUniformMatrix4fv(matLoc, 1, false, transformMatrix, 0)
        GLES30.glEnableVertexAttribArray(0)
        GLES30.glVertexAttribPointer(0, 3, GLES30.GL_FLOAT, false, 0, vertexBuffer)
        GLES30.glEnableVertexAttribArray(1)
        GLES30.glVertexAttribPointer(1, 2, GLES30.GL_FLOAT, false, 0, texPosBuffer)
        GLES30.glDrawElements(GLES30.GL_TRIANGLES, indexData.size, GLES30.GL_UNSIGNED_SHORT, vertexIndexBuffer)

        readFrame()
    }

    // todo 修复图像颠倒的问题
    private fun readFrame(width: Int = this.width, height: Int = this.height) {
        printDelay("readFrame")
        val buffer: ByteBuffer = ByteBuffer.allocate(width * height * 4) // 一个argb像素含4字节
        GLES30.glReadPixels(0, 0, width, height, GLES30.GL_RGBA, GLES30.GL_UNSIGNED_BYTE, buffer)
        val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
        buffer.rewind()
        bitmap.copyPixelsFromBuffer(buffer)
        bitmap?.recycle()
    }
}